<template>
  <div class="knowledge-folder-tree">
    <div class="tree-header">
      <h3>文件夹</h3>
      <div class="tree-actions">
        <el-button
          text
          size="small"
          @click="handleCreateFolder"
          title="新建文件夹"
        >
          <el-icon><Plus /></el-icon>
        </el-button>
      </div>
    </div>
    <div class="tree-body" v-loading="loading">
      <el-tree
        ref="treeRef"
        :data="folderTree"
        :props="treeProps"
        node-key="id"
        :default-expand-all="false"
        :expand-on-click-node="false"
        :highlight-current="true"
        :current-node-key="currentFolderId"
        @node-click="handleNodeClick"
        class="folder-tree"
      >
        <template #default="{ node, data }">
          <div 
            class="tree-node"
            @contextmenu.prevent="handleContextMenu($event, data)"
            @dragstart="handleDragStart($event, data)"
            @dragover="handleDragOver($event, data)"
            @drop="handleDrop($event, data)"
            @dragend="handleDragEnd"
            draggable="true"
          >
            <el-icon class="folder-icon"><Folder /></el-icon>
            <span class="folder-name">{{ node.label }}</span>
            <span class="file-count" v-if="data.file_count > 0">({{ data.file_count }})</span>
            <div class="node-actions" @click.stop>
              <el-dropdown trigger="click" @command="(cmd) => handleAction(cmd, data)">
                <el-button text circle size="small" class="action-btn">
                  <el-icon><MoreFilled /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="create-child">
                      <el-icon><Plus /></el-icon>
                      新建子文件夹
                    </el-dropdown-item>
                    <el-dropdown-item command="upload-file">
                      <el-icon><Upload /></el-icon>
                      上传文件
                    </el-dropdown-item>
                    <el-dropdown-item command="edit" divided>
                      <el-icon><Edit /></el-icon>
                      编辑
                    </el-dropdown-item>
                    <el-dropdown-item command="delete" class="danger-item">
                      <el-icon><Delete /></el-icon>
                      删除
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </div>
        </template>
      </el-tree>
      <el-empty
        v-if="!loading && folderTree.length === 0"
        description="暂无文件夹"
        :image-size="80"
      >
        <template #image>
          <el-icon :size="80" color="var(--el-text-color-placeholder)">
            <FolderOpened />
          </el-icon>
        </template>
        <el-button type="primary" @click="handleCreateFolder">
          <el-icon><Plus /></el-icon>
          创建第一个文件夹
        </el-button>
      </el-empty>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { 
  Folder, 
  FolderOpened,
  Plus, 
  MoreFilled, 
  Upload, 
  Edit, 
  Delete 
} from '@element-plus/icons-vue'
import { 
  getKnowledgeFolders, 
  deleteKnowledgeFolder,
  updateKnowledgeFolder,
  type KnowledgeFolder 
} from '@/api/knowledge'
import { ResponseParser } from '@/utils/responseParser'

interface Props {
  currentFolderId?: string
}

interface Emits {
  (e: 'folder-selected', folderId: string | undefined): void
  (e: 'create-folder', parentId?: string): void
  (e: 'edit-folder', folder: KnowledgeFolder): void
  (e: 'upload-file', folderId: string): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const treeRef = ref()
const loading = ref(false)
const folderTree = ref<KnowledgeFolder[]>([])
const draggedFolder = ref<KnowledgeFolder | null>(null)

const treeProps = {
  label: 'name',
  children: 'children'
}

// 加载文件夹树
const loadFolderTree = async () => {
  try {
    loading.value = true
    const response = await getKnowledgeFolders({ tree: true })
    const parsed = ResponseParser.parseResponse<KnowledgeFolder[]>(response)
    
    if (parsed.success && parsed.data) {
      folderTree.value = parsed.data || []
      
      // 展开当前选中节点的所有父节点
      if (props.currentFolderId) {
        nextTick(() => {
          expandToNode(props.currentFolderId!)
        })
      }
    } else {
      folderTree.value = []
      ElMessage.error(parsed.message || '加载文件夹列表失败')
    }
  } catch (error: any) {
    console.error('加载文件夹列表失败:', error)
    ElMessage.error('加载文件夹列表失败')
    folderTree.value = []
  } finally {
    loading.value = false
  }
}

// 展开到指定节点
const expandToNode = (nodeId: string) => {
  const findNode = (nodes: KnowledgeFolder[], targetId: string, path: string[] = []): string[] | null => {
    for (const node of nodes) {
      const currentPath = [...path, node.id]
      if (node.id === targetId) {
        return currentPath
      }
      if (node.children && node.children.length > 0) {
        const result = findNode(node.children, targetId, currentPath)
        if (result) {
          return result
        }
      }
    }
    return null
  }
  
  const path = findNode(folderTree.value, nodeId)
  if (path) {
    path.forEach(id => {
      const node = treeRef.value?.getNode(id)
      if (node && !node.expanded) {
        node.expand()
      }
    })
  }
}

// 节点点击
const handleNodeClick = (data: KnowledgeFolder) => {
  emit('folder-selected', data.id)
}

// 创建文件夹
const handleCreateFolder = () => {
  emit('create-folder', props.currentFolderId)
}

// 操作处理
const handleAction = (command: string, folder: KnowledgeFolder) => {
  switch (command) {
    case 'create-child':
      emit('create-folder', folder.id)
      break
    case 'upload-file':
      emit('upload-file', folder.id)
      break
    case 'edit':
      emit('edit-folder', folder)
      break
    case 'delete':
      handleDeleteFolder(folder)
      break
  }
}

// 删除文件夹
const handleDeleteFolder = async (folder: KnowledgeFolder) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除文件夹 "${folder.name}" 吗？\n此操作将删除文件夹及其所有内容，且无法恢复。`,
      '删除文件夹',
      {
        type: 'warning',
        confirmButtonText: '确定删除',
        cancelButtonText: '取消'
      }
    )

    await deleteKnowledgeFolder(folder.id)
    ElMessage.success('删除成功')
    loadFolderTree()
    
    // 如果删除的是当前选中的文件夹，切换到根目录
    if (props.currentFolderId === folder.id) {
      emit('folder-selected', undefined)
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('删除文件夹失败:', error)
      ElMessage.error(error?.response?.data?.detail || error?.response?.data?.message || '删除失败')
    }
  }
}

// 右键菜单
const handleContextMenu = (event: MouseEvent, folder: KnowledgeFolder) => {
  // 可以在这里添加自定义右键菜单
  // 目前使用下拉菜单代替
}

// 拖拽开始
const handleDragStart = (event: DragEvent, folder: KnowledgeFolder) => {
  if (event.dataTransfer) {
    event.dataTransfer.effectAllowed = 'move'
    event.dataTransfer.setData('folder-id', folder.id)
    event.dataTransfer.setData('drag-type', 'folder')
  }
  draggedFolder.value = folder
  const target = event.currentTarget as HTMLElement
  if (target) {
    target.classList.add('dragging')
  }
}

// 拖拽悬停
const handleDragOver = (event: DragEvent, folder: KnowledgeFolder) => {
  event.preventDefault()
  if (event.dataTransfer) {
    event.dataTransfer.dropEffect = 'move'
  }
  
  // 检查是否会造成循环引用
  if (draggedFolder.value && isDescendant(folder, draggedFolder.value)) {
    return
  }
  
  const target = event.currentTarget as HTMLElement
  if (target && draggedFolder.value && draggedFolder.value.id !== folder.id) {
    target.classList.add('drag-over')
  }
}

// 拖拽放置
const handleDrop = async (event: DragEvent, targetFolder: KnowledgeFolder) => {
  event.preventDefault()
  const target = event.currentTarget as HTMLElement
  if (target) {
    target.classList.remove('drag-over')
    target.classList.remove('dragging')
  }

  if (!draggedFolder.value || draggedFolder.value.id === targetFolder.id) {
    draggedFolder.value = null
    return
  }

  // 检查是否会造成循环引用
  if (isDescendant(targetFolder, draggedFolder.value)) {
    ElMessage.warning('不能将文件夹移动到其子文件夹下')
    draggedFolder.value = null
    return
  }

  try {
    const response = await updateKnowledgeFolder(draggedFolder.value.id, {
      parent_id: targetFolder.id
    })
    const parsed = ResponseParser.parseResponse<KnowledgeFolder>(response)
    if (parsed.success && parsed.data) {
      ElMessage.success('移动成功')
      loadFolderTree()
    } else {
      ElMessage.error(parsed.message || '移动失败')
    }
  } catch (error: any) {
    console.error('移动文件夹失败:', error)
    ElMessage.error(error?.response?.data?.detail || error?.response?.data?.message || '移动失败')
  } finally {
    draggedFolder.value = null
  }
}

// 拖拽结束
const handleDragEnd = () => {
  // 清除所有拖拽样式
  document.querySelectorAll('.drag-over, .dragging').forEach(el => {
    el.classList.remove('drag-over', 'dragging')
  })
  draggedFolder.value = null
}

// 检查是否是子节点（用于防止循环引用）
const isDescendant = (ancestor: KnowledgeFolder, descendant: KnowledgeFolder): boolean => {
  if (!ancestor.children || ancestor.children.length === 0) {
    return false
  }
  
  for (const child of ancestor.children) {
    if (child.id === descendant.id) {
      return true
    }
    if (child.children && child.children.length > 0) {
      if (isDescendant(child, descendant)) {
        return true
      }
    }
  }
  
  return false
}


// 监听当前文件夹ID变化
watch(() => props.currentFolderId, (newId) => {
  if (newId && treeRef.value) {
    nextTick(() => {
      expandToNode(newId)
    })
  }
})

onMounted(() => {
  loadFolderTree()
})

// 导出刷新方法供外部调用
defineExpose({
  refresh: loadFolderTree
})
</script>

<style scoped lang="scss">
.knowledge-folder-tree {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-right: 1px solid var(--el-border-color);

  .tree-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px;
    border-bottom: 1px solid var(--el-border-color);

    h3 {
      margin: 0;
      font-size: 16px;
      font-weight: 600;
      color: var(--el-text-color-primary);
    }

    .tree-actions {
      display: flex;
      gap: 4px;
    }
  }

  .tree-body {
    flex: 1;
    overflow-y: auto;
    padding: 8px;

    .folder-tree {
      :deep(.el-tree-node) {
        .tree-node {
          display: flex;
          align-items: center;
          gap: 8px;
          flex: 1;
          width: 100%;

          .folder-icon {
            color: var(--el-color-warning);
            font-size: 16px;
          }

          .folder-name {
            flex: 1;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
          }

          .file-count {
            font-size: 12px;
            color: var(--el-text-color-secondary);
          }
        }
      }

      :deep(.el-tree-node__content) {
        height: 36px;
        padding: 0 8px;
        position: relative;
        transition: all 0.2s;

        &:hover {
          background-color: var(--el-fill-color-light);
          
          .node-actions {
            opacity: 1;
          }
        }

        &.drag-over {
          background-color: var(--el-color-primary-light-9) !important;
          border: 2px dashed var(--el-color-primary) !important;
          border-radius: 4px;
          transform: scale(1.02);
        }

        &.dragging {
          opacity: 0.5;
          cursor: move;
        }
      }

      :deep(.el-tree-node.is-current > .el-tree-node__content) {
        background-color: var(--el-color-primary-light-9);
        color: var(--el-color-primary);
      }

      .tree-node {
        position: relative;
        width: 100%;

        .node-actions {
          position: absolute;
          right: 8px;
          opacity: 0;
          transition: opacity 0.2s;
          z-index: 10;

          .action-btn {
            padding: 4px;
          }
        }

        &:hover .node-actions {
          opacity: 1;
        }
      }
    }
  }
}

:deep(.el-dropdown-menu__item.danger-item) {
  color: var(--el-color-danger);

  &:hover {
    background-color: var(--el-color-danger-light-9);
  }
}
</style>

